package com.bytz.modules.cms.order.pay.util;

import com.bytz.modules.cms.domain.model.pay.BalancePayIn;
import com.bytz.modules.cms.domain.model.pay.BalancePayItem;
import com.bytz.modules.cms.domain.model.pay.PrepayIn;
import com.bytz.modules.cms.order.entity.*;
import com.bytz.modules.cms.order.model.OfflinePayIn;
import com.bytz.modules.cms.order.model.PayNotifyResult;
import com.bytz.modules.cms.order.model.PayResponse;
import com.bytz.modules.cms.order.model.PayResponseStatus;
import com.bytz.modules.cms.order.service.*;
import com.bytz.modules.cms.util.EntityChecker;
import com.bytz.modules.cms.util.EntityFieldChecker;
import org.junit.jupiter.api.Assertions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PayTestUtil {

    public static PayNotifyResult buildPayNotifyResult(String payDetailId, String code, String message, PayResponseStatus status) {
        PayNotifyResult payNotifyResult = new PayNotifyResult();
        payNotifyResult.setPayDetailId(payDetailId);
        payNotifyResult.setPaySource("建设银行");
        payNotifyResult.setPayResponse(new PayResponse(code, message, status));
        payNotifyResult.setTransactionNumber("000000000001");
        payNotifyResult.setCompleteDate("20221118");
        payNotifyResult.setCode("0000");

        return payNotifyResult;
    }

    public static void checkOfflinePay(OrderOfflinePay offlinePay, EntityFieldChecker<OrderOfflinePay> checkers) {
        checkers.doCheck(offlinePay, "汇票");
    }

    public static void checkOfflinePays(String orderPayId, IOrderPayDetailService orderPayDetailService, IOrderOfflinePayService orderOfflinePayService, EntityChecker<OrderOfflinePay> checkers) {
        List<OrderPayDetail> orderPayDetails = orderPayDetailService.getOfflinePayByPayId(orderPayId);
        Set<String> offPayIds = orderPayDetails.stream().map(OrderPayDetail::getOfflinePayId).collect(Collectors.toSet());

        List<OrderOfflinePay> offlinePays = orderOfflinePayService.getByIds(offPayIds);

        Assertions.assertEquals(checkers.size(), offlinePays.size(), "汇票个数不正确");
        checkers.doCheck(offlinePays);
    }

    public static void checkPickUps(String orderPayId, IOrderPickUpDetailService orderPickUpDetailService, EntityChecker<OrderPickUpDetail> checkers) {
        List<OrderPickUpDetail> orderPayDetails = orderPickUpDetailService.getByOrderPayId(orderPayId);

        Assertions.assertEquals(checkers.size(), orderPayDetails.size(), "提货数据个数不正确");
        checkers.doCheck(orderPayDetails);
    }

    public static void checkPickUp(OrderPickUpDetail pickUpDetail, EntityFieldChecker<OrderPickUpDetail> checkers) {
        checkers.doCheck(pickUpDetail, "提货明细");
    }

    public static void checkOrderItems(String orderId, IOrderItemService orderItemService, EntityChecker<OrderItem> entityCheckerItems) {
        List<OrderItem> orderItems = orderItemService.getByOrderId(orderId);

        entityCheckerItems.doCheck(orderItems);
    }

    public static void checkOrderItem(OrderItem orderItem, EntityFieldChecker<OrderItem> checkers) {
        checkers.doCheck(orderItem, "订单明细");
    }

    public static void checkOrder(String orderId, IOrderService orderService, EntityFieldChecker<Order> fieldCheckers) {
        Order order = orderService.getById(orderId);
        fieldCheckers.doCheck(order, "订单");
    }

    public static void checkOrderPayDetails(String orderPayId, IOrderPayDetailService orderPayDetailService, EntityChecker<OrderPayDetail> payDetailCheckers) {
        List<OrderPayDetail> orderPayDetails = orderPayDetailService.getByPayId(orderPayId);

        Assertions.assertEquals(payDetailCheckers.size(), orderPayDetails.size(), "支付明细个数不正确");
        payDetailCheckers.doCheck(orderPayDetails);
    }

    public static void checkOrderPayDetail(OrderPayDetail payDetail, EntityFieldChecker<OrderPayDetail> fieldCheckers) {
        fieldCheckers.doCheck(payDetail, "支付明细");
    }

    public static OrderPay checkOrderPay(String orderId, IOrderPayService orderPayService, Predicate<OrderPay> predicate, EntityFieldChecker<OrderPay> fieldCheckers) {
        List<OrderPay> orderPaysInDb = orderPayService.getByOrderId(orderId);

        List<OrderPay> orderPays = orderPaysInDb.stream().filter(predicate).collect(Collectors.toList());

        Assertions.assertEquals(1, orderPays.size(), "应该有1条支付主记录");

        OrderPay orderPay = orderPays.get(0);
        fieldCheckers.doCheck(orderPay, "支付主数据");

        return orderPay;
    }

    /**
     * 构建预付-仅在线-入参
     */
    public static PrepayIn buildPrepayOnlyOnlineIn(String orderId) {
        PrepayIn prepayIn = new PrepayIn();
        prepayIn.setOrderId(orderId);
        prepayIn.setOfflinePays(new ArrayList<>());
        return prepayIn;
    }

    /**
     * 构建首付有汇票的准备入参
     */
    public static PrepayIn buildPrepayPrepareHasOfflineIn(String orderId, String offlinePayId1, String offlinePayId2) {
        PrepayIn prepayIn = new PrepayIn();
        prepayIn.setOrderId(orderId);

        OfflinePayIn offlinePayIn1 = new OfflinePayIn();
        offlinePayIn1.setId(offlinePayId1);
        offlinePayIn1.setRemitName("汇票1");
        OfflinePayIn offlinePayIn2 = new OfflinePayIn();
        offlinePayIn2.setId(offlinePayId2);
        offlinePayIn2.setRemitName("汇票2");

        prepayIn.setOfflinePays(Arrays.asList(offlinePayIn1, offlinePayIn2));
        return prepayIn;
    }

    public static BalancePayIn buildBalancePayOnlyOnlineIn(String orderId, List<BalancePayItem> balancePayItems) {
        BalancePayIn balancePayIn = new BalancePayIn();
        balancePayIn.setOrderId(orderId);
        balancePayIn.setShipToAddress("邮寄地址");
        balancePayIn.setShipToContact("邮寄联系人");
        balancePayIn.setShipToName("邮寄企业名称");
        balancePayIn.setShipToNumber("邮寄企业编码");
        balancePayIn.setShipToPhone("邮寄企业电话");

        balancePayIn.setPayItems(balancePayItems);

        return balancePayIn;
    }

    public static BalancePayIn buildBalancePayHasOfflineIn(String orderId, List<BalancePayItem> balancePayItems, String... offlinePayIds) {
        BalancePayIn balancePayIn = new BalancePayIn();
        balancePayIn.setOrderId(orderId);
        balancePayIn.setShipToAddress("邮寄地址");
        balancePayIn.setShipToContact("邮寄联系人");
        balancePayIn.setShipToName("邮寄企业名称");
        balancePayIn.setShipToNumber("邮寄企业编码");
        balancePayIn.setShipToPhone("邮寄企业电话");

        balancePayIn.setPayItems(balancePayItems);

        List<OfflinePayIn> offlinePayIns = new ArrayList<>();
        balancePayIn.setOfflinePays(offlinePayIns);

        for (int i = 0; i < offlinePayIds.length; i++) {
            OfflinePayIn offlinePayIn = new OfflinePayIn();
            offlinePayIn.setId(offlinePayIds[i]);
            offlinePayIn.setRemitName("汇票" + i);

            offlinePayIns.add(offlinePayIn);
        }

        return balancePayIn;
    }

    public static BalancePayItem buildBalancePayItem(String orderItemId, int shippedNumber) {
        BalancePayItem balancePayItem = new BalancePayItem();
        balancePayItem.setOrderItemId(orderItemId);
        balancePayItem.setShippedNumber(shippedNumber);

        return balancePayItem;
    }
}
